/** @file ADE7763.h
 *  @author Lukáš Michalík
 *  @version 1.0.0
 *  @date 16.4.2013
 */

#ifndef ADE7763_H_
#define ADE7763_H_

/** @addtogroup RaspBerryPi_Power_Control
  * @{
  */

/** @addtogroup ADE_7763
  * @{
  */

/* Exported constants --------------------------------------------------------*/

/** @defgroup ADE_7763_Exported_Constants
  * @{
  */

/** @defgroup ADE_7763_Text_output
  * @{
  */

const char* const list[] = { "NONE", "WAVEFORM", "AENERGY", "RAENERGY",
		"LAENERGY", "VAENERGY", "RVAENERGY", "LVAENERGY", "RESERVED", "MODE",
		"IRQEN", "STATUS", "RSTSTATUS", "CH1OS", "CH2OS", "GAIN", "PHCAL",
		"APOS", "WGAIN", "WDIV", "CFNUM", "CFDEN", "IRMS", "VRMS", "IRMSOS",
		"VRMSOS", "VAGAIN", "VADIV", "LINECYC", "ZXTOUT", "SAGCYC", "SAGLVL",
		"IPKLVL", "VPKLVL", "IPEAK", "RSTIPEAK", "VPEAK", "RSTVPEAK", "TEMP",
		"PERIOD", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED",
		"RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED",
		"RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED",
		"RESERVED", "RESERVED", "RESERVED", "RESERVED", "TMODE", "CHKSUM",
		"DIEREV" };

const unsigned char RegLength[] = { 24, 24, 24, 24, 24, 24, 24, 0, 16, 16, 16,
		16, 8, 8, 8, 6, 16, 12, 8, 12, 12, 24, 24, 12, 12, 12, 8, 16, 12, 8, 8,
		8, 8, 24, 24, 24, 24, 8, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
		0, 0, 0, 0, 0, 0, 0, 8, 6, 8

};

const char* const RegPermmision[] = { "R", "R", "R", "R", "R", "R", "R", "N",
		"R/W", "R/W", "R", "R", "R/W", "R/W", "R/W", "R/W", "R/W", "R/W", "R/W",
		"R/W", "R/W", "R", "R", "R/W", "R/W", "R/W", "R/W", "R/W", "R/W", "R/W",
		"R/W", "R/W", "R/W", "R", "R", "R", "R", "R", "R", "N", "N", "N", "N",
		"N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N",
		"N", "N", "N", "R/W", "R", "R" };

const char* const RegDescription[] = {
		"Obsahuje vzorkovaný průběh dat Kanálu1, Kanálu2 nebo činný výkon sygnálu. Mode reg. bit 14 a 13.",
		"Činný výkon integrvaný v čase.",
		"Činný výkon integrvaný v čase, nuluje se při operaci čtení.",
		"Okamžitý činný výkon accumulated in this register over the LINECYC number of half line cycles. ",
		"Zdánlivý výkon akumulovaný v čase.",
		"Zdánlivý výkon akumulovaný v čase, nuluje se při operaci čtení.",
		"Okamžitý zdánlivý výkon is accumulated in this register over the LINECYC number of half line cycles.",
		"N",
		"Konfigurační register - Signal sample rates, filter enabling, calibration",
		"Přerušení je standardně vypnuto, aktivace příslošného přerušení pomocí 0. ",
		"Informace o přerušeních, reaguje i při vyplém přerušeni",
		"Informace o přerušení, nulují se při operaci čtení",
		"BIT 0-5 offset Kanál 1, Bit 6 nevyužitý, MSB integrátor off/on 0/1. ",
		"Bit 6 a 7 nevyužit. Bit 0-5 offset kanál 2. INVERTED read manual.",
		"PGA Kanál 1 a 2.",
		"Fázová kalibrace mezi kanálem 1 a 2",
		"Korekce činného výkonu",
		"Kalibrace kalkulace činného výkony při zápisu do registru +-50%",
		"Interní integrační register činného výkonu",
		"CF Frequency Divider Numerator Register.",
		"CF Frequency Divider Denominator Register. ",
		"Channel 1 RMS Value (Current Channel).",
		"Channel 2 RMS Value (Voltage Channel).",
		"Channel 1 RMS Offset Correction Register.",
		"Channel 2 RMS Offset Correction Register.",
		"Kalibrace kalkulace zdánlivého výkony při zápisu do registru +-50%",
		"Interní integrační register zdánlivého výkonu",
		"Register pro výpočet půlperiody",
		"Zero-Crossing Timeout Kanál 2 ???",
		"Sag Line Cycle Register.",
		"Sag Voltage Level. ",
		"Channel 1 Peak Level Threshold (Current Channel), při překročení nastaví PKI flag",
		"Channel 2 Peak Level Threshold (Voltage Channel), při překročení nastaví PKV flag.",
		"Obsahuje maximální hodnotu peeku zaznamenanou od posledního čtení Kanál 1.",
		"Obsahuje maximální hodnotu peeku zaznamenanou od posledního čtení Kanál 1, po přečtení se nuluje.",
		"Obsahuje maximální hodnotu peeku zaznamenanou od posledního čtení Kanál 2.",
		"Obsahuje maximální hodnotu peeku zaznamenanou od posledního čtení Kanál 2, po přečtení se nuluje.",
		"Výsledek poslední teplotní converze",
		"Perioda napěťového kanálu",
		"N", "N", "N", "N",
		"N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N",
		"N", "N", "N",
		"Test Mode Register.",
		"Checksum Register.",
		"Die Revision Register. " };

const char* const InterupFlagsName7763[] = { "AEHF", "SAG", "CYCEND", "WSMP",
		"ZX", "TEMP", "RESET", "AEOF", "PKV", "PKI", "VAEHF", "VAEOF", "ZXTO",
		"PPOS", "PNEG", "RESERVED" };

const char* const InterupFlagsDescription7763[] = {
		""
};


const char* const SpiMode[] = { "READ", "WRITE"
};

#define PRINT_REGISTE_TABLE_HEAD  printf("ADRESA |    NAME    | DELKA | PER | W | DATA \n"); printf("_____________________________________________\n")
/**
  * @}
  */

/** @defgroup ADE_7763_SPI_setup
  * @{
  */

#define SPI1 1 								/*!< Nastavuej příslušný CE pro SPI komunikaci 1 - CE1 a 0 - CE0.  */
#define SPI0 0								/*!< Nastavuej příslušný CE pro SPI komunikaci 1 - CE1 a 0 - CE0.  */
#define POCET_REGISTRU_ADE7763 0x3F			/*!< Celkový počer registrů ADE7763, Maska pro čtení.  */
#define SPI_ADE7763_SPEED 30500				/*!< Bitová rychlost SPI komunikace.  */

#define SPIREAD 0							/*!< Určuje směr SPI komunikace, čtení nebo zápis. 0 čtení,1 zápis */
#define SPIWRITE 1							/*!< Určuje směr SPI komunikace, čtení nebo zápis. 0 čtení,1 zápis */

#define MaxBuffSize  4  /*!< maximální délka pole sloužícího pro komunikaci SPI (počet přenášených bytů) + adresa */

/**
  * @}
  */

/** @defgroup ADE_7763_Text_output_setup
  * @{
  */

#define VERBOSE_MODE 1						/*!< Rozšířený textový výstup.  */
#define NON_VERBOSE_MODE 0					/*!< Základní textový výstup.  */
#define FAST 0								/*!< Ryclé průměrování - orientační. Použití if(ryclost) {delay(20);}  */
#define NON_FAST 1							/*!< Pomalé průměrování naměřených hodnot. Použití if(ryclost) {delay(20);}*/

/**
  * @}
  */

/** @defgroup ADE_7763_IRMS_measurement_parameters
  * @{
  */

//IRMS
#define IRMSMAXSCALE5 1868467 //0x1C82B3	/*!< Maximální vstupní napětí z bočníku, přepočítané na vstupní rozsah 0.5V, vyjádřené po AD převodu */
#define IRMSMAXSCALE25 934233				/*!< Maximální vstupní napětí z bočníku, přepočítané na vstupní rozsah 0.25V, vyjádřené po AD převodu */
#define IRMSMAXSCALE125 467116				/*!< Maximální vstupní napětí z bočníku, přepočítané na vstupní rozsah 0.125V, vyjádřené po AD převodu */
#define IRMSMAXSCALE125G2 233558			/*!< Maximální vstupní napětí z bočníku, přepočítané na vstupní rozsah 0.5V, vyjádřené po AD převodu, zohledněn vstupní Gain 2 */
#define IRMSMAXSCALE125G4 116779			/*!< Maximální vstupní napětí z bočníku, přepočítané na vstupní rozsah 0.5V, vyjádřené po AD převodu, zohledněn vstupní Gain 4 */
#define IRMSMAXSCALE125G8 58389				/*!< Maximální vstupní napětí z bočníku, přepočítané na vstupní rozsah 0.5V, vyjádřené po AD převodu, zohledněn vstupní Gain 8 */
#define IRMSMAXSCALE125G16 29194			/*!< Maximální vstupní napětí z bočníku, přepočítané na vstupní rozsah 0.5V, vyjádřené po AD převodu, zohledněn vstupní Gain 16 */


#define IRMSINSCALE5 0.5					/*!< Definice vstpního rozsahu AD převodníku 0.5V (proudového kanálu 1). */
#define IRMSINSCALE25 0.25					/*!< Definice vstpního rozsahu AD převodníku 0.25V (proudového kanálu 1). */
#define IRMSINSCALE125 0.125				/*!< Definice vstpního rozsahu AD převodníku 0.125V (proudového kanálu 1). */

#define RBOCNIK 0.0005						/*!< Definice Velikosti proudového bočníku V Ohmech */
#define POCETPRUMEROVACICHCIKLU  100		/*!< Počet průměrovacích ciklů na jedno měření respektive velikost kruhového bufferu */
#define RYCHLYPRUMER  20		/*!< Počet průměrovacích ciklů na jedno proudové měření */


//#define IRMSHRARDOFFSET ((-1)*0.000408716)
#define IRMSHRARDOFFSET 0//((-1)*0.0005717811)	/*!< Konstatní Offset proudového měření */
#define IRMSHRARDOFFSETSCALE125G16 ((-1)*0.000131287539)
#define IRMSHRARDOFFSETSCALE125G8 IRMSHRARDOFFSETSCALE125G16
#define IRMSHRARDOFFSETSCALE125G4 IRMSHRARDOFFSETSCALE125G16
#define IRMSHRARDOFFSETSCALE125G2 IRMSHRARDOFFSETSCALE125G16
/**
  * @}
  */


/** @defgroup ADE_7763_VRMS_measurement_parameters
  * @{
  */
//VRMS
#define VRMSOUTSCALE 0x17D338				/*!< Maximální vstupní napětí napěťového děliče, přepočítané na vstupní rozsah 0.5V, vyjádřené po AD převodu */
#define VRMSINSCALE 0.5						/*!< Vstupní rozsah napěťového kanálu. Kanál 2 */
#define VRMSBOCNIKR1 600000					/*!< Napěťový dělič, Rezistor R1 */
#define VRMSBOCNIKR2 1000					/*!< Napěťový dělič, Rezistor R2 výstupní napětí pro AD převod */
#define VRMSHRARDOFFSET ((-1)*0.182)		/*!< Konstatní Offset napěťového měření */


/**
  * @}
  */

/** @defgroup ADE_7763_Temperature_measurement_parameters
  * @{
  */
//definice z datasheetu
#define LSBOFPERIOD 2.2/1000000
#define LSBOFTEMP 1.5 - 25
#define KOREKCETEPLOTY ((+1)*17.5) //19.5

/**
  * @}
  */



/** @defgroup ADE_7763_address_Register
  */



#define	ADRWAVEFORM 	0x01
#define	ADRAENERGY 	0x02
#define	ADRRAENERGY 	0x03
#define	ADRLAENERGY 	0x04
#define	ADRVAENERGY 	0x05
#define	ADRRVAENERGY 	0x06
#define	ADRLVAENERGY 	0x07
//#define	ADR	RESERVED 	0x08
#define	ADRMODE 	0x09
#define	ADRIRQEN 	0x0a
#define	ADRSTATUS 	0x0b
#define	ADRRSTSTATUS 	0x0c
#define	ADRCH1OS 	0x0d
#define	ADRCH2OS 	0x0e
#define	ADRGAIN 	0x0f
#define	ADRPHCAL 	0x10
#define	ADRAPOS 	0x11
#define	ADRWGAIN 	0x12
#define	ADRWDIV 	0x13
#define	ADRCFNUM 	0x14
#define	ADRCFDEN 	0x15
#define	ADRIRMS 	0x16
#define	ADRVRMS 	0x17
#define	ADRIRMSOS 	0x18
#define	ADRVRMSOS 	0x19
#define	ADRVAGAIN 	0x1a
#define	ADRVADIV 	0x1b
#define	ADRLINECYC 	0x1c
#define	ADRZXTOUT 	0x1d
#define	ADRSAGCYC 	0x1e
#define	ADRSAGLVL 	0x1f
#define	ADRIPKLVL 	0x20
#define	ADRVPKLVL 	0x21
#define	ADRIPEAK 	0x22
#define	ADRRSTIPEAK 	0x23
#define	ADRVPEAK 	0x24
#define	ADRRSTVPEAK 	0x25
#define	ADRTEMP 	0x26
#define	ADRPERIOD 	0x27
//#define	ADR	RESERVED 	0x28
//#define	ADR	RESERVED 	0x29
//#define	ADR	RESERVED 	0x2a
//#define	ADR	RESERVED 	0x2b
//#define	ADR	RESERVED 	0x2c
//#define	ADR	RESERVED 	0x2d
//#define	ADR	RESERVED 	0x2e
//#define	ADR	RESERVED 	0x2f
//#define	ADR	RESERVED 	0x30
//#define	ADR	RESERVED 	0x31
//#define	ADR	RESERVED 	0x32
//#define	ADR	RESERVED 	0x33
//#define	ADR	RESERVED 	0x34
//#define	ADR	RESERVED 	0x35
//#define	ADR	RESERVED 	0x36
//#define	ADR	RESERVED 	0x37
//#define	ADR	RESERVED 	0x38
//#define	ADR	RESERVED 	0x39
//#define	ADR	RESERVED 	0x3a
//#define	ADR	RESERVED 	0x3b
//#define	ADR	RESERVED 	0x3c
#define	ADRTMODE 	0x3d
#define	ADRCHKSUM 	0x3e
#define	ADRDIEREV 	0x3f

/**
  * @}
  */

typedef struct kruhac {
	float Prum_pole[POCETPRUMEROVACICHCIKLU];
	uint8_t pozice;
} T_kruh_buffer;


void ade7763ReadAll(int kanal);
void ade7763WriteTest(void);
int ade7763ReadWrite(uint8_t kanal,uint8_t* buffer, uint8_t mode, uint8_t verbose);
void PrintRegisterTableLine (uint8_t* buffer,uint8_t bufsize, uint8_t Regtmp );
void IrmsCalibrate(void);
void GetStatus7763 (void);
void GetRstStatus7763(void);
float GetFrequency7763 (uint8_t verbose);
void SetTemperature7763(uint8_t stav);
float GetTemperature7763(uint8_t verbose);
float GetVrms7763(uint8_t verbose);
void SetVrmsOS7763(uint16_t VrmsOS);
float GetIrms7763(uint8_t verbose, uint8_t fast) ;


void SetScalePGA17763(uint8_t scale, uint8_t verbose);
void SetGainPGA17763(uint8_t GainSet, uint8_t verbose);
void SetGainPGA27763(uint8_t GainSet);
float GetAutoIrms7763(uint8_t verbose);
float fakewatt(float proud, float napeti);

/**
  * @}
  */

/**
  * @}
  */

/**
  * @}
  */

#endif /* ADE7763_H_ */
